package com.ciaojian.client.util;


import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * Request封装类
 *
 * @author
 */
public class RequestUtil {

    /**
     * 未知域名
     */
    private static final String IP_UNKNOWN = "unknown";

    /**
     * 获取客户端IP地址，此方法用在proxy环境中
     *
     * @param request
     * @return
     */
    public static String getRemoteAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isEmpty(ip) || ip.equalsIgnoreCase(IP_UNKNOWN)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isEmpty(ip) || ip.equalsIgnoreCase(IP_UNKNOWN)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isEmpty(ip) || ip.equalsIgnoreCase(IP_UNKNOWN)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (StringUtils.isEmpty(ip) || ip.equalsIgnoreCase(IP_UNKNOWN)) {
            ip = request.getRemoteAddr();
        }
        // 多级反向代理检测
        if (ip != null && ip.indexOf(",") > 0) {
            ip = ip.trim().split(",")[0];
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }

    /**
     * 获得参数值
     *
     * @param request
     * @param name
     * @param defaultValue
     * @return
     */
    public static String get(HttpServletRequest request, String name, String defaultValue) {
        return request.getParameter(name) != null ? request.getParameter(name) : defaultValue;
    }

    /**
     * 获得参数值
     *
     * @param request
     * @param name
     * @return
     */
    public static String get(HttpServletRequest request, String name) {
        return get(request, name, "");
    }

    /**
     * 获得int值
     *
     * @param request
     * @param name
     * @param defaultValue
     * @return
     */
    public static int getInt(HttpServletRequest request, String name, int defaultValue) {
        return Conver.toInt(request.getParameter(name), defaultValue);
    }

    /**
     * 获得int值
     *
     * @param request
     * @param name
     * @return
     */
    public static int getInt(HttpServletRequest request, String name) {
        return getInt(request, name, 0);
    }

    /**
     * 获得float值
     *
     * @param request
     * @param name
     * @param defaultValue
     * @return
     */
    public static float getFloat(HttpServletRequest request, String name, float defaultValue) {
        return Conver.toFloat(request.getParameter(name), defaultValue);
    }

    /**
     * 获得double值
     *
     * @param request
     * @param name
     * @param defaultValue
     * @return
     */
    public static double getDouble(HttpServletRequest request, String name, double defaultValue) {
        return Conver.toDouble(request.getParameter(name), defaultValue);
    }

    /**
     * 获得long值
     *
     * @param request
     * @param name
     * @param defaultValue
     * @return
     */
    public static long getLong(HttpServletRequest request, String name, long defaultValue) {
        return Conver.toLong(request.getParameter(name), defaultValue);
    }

    /**
     * 获取参数值数组
     *
     * @param request
     * @param paramName
     * @return
     */
    public static String[] getValues(HttpServletRequest request, String paramName) {
        return request.getParameterValues(paramName);
    }

    /**
     * 获取参数的数字值组合成一个字符串
     *
     * @param request
     * @param paramName
     * @param separator 分隔符
     * @return
     */
    public static String getValues(HttpServletRequest request, String paramName, String separator) {
        String[] values = request.getParameterValues(paramName);
        return StringUtils.join(separator, true, values);
    }

    /**
     * 取得表单里面所有的参数/值<br>
     * 多个值的默认以逗号隔开保存
     *
     * @param request
     * @param notStart
     * @return
     */
    public static Map<String, Object> getParam(HttpServletRequest request, String notStart) {
        return getParam(request, notStart, ",");
    }

    /**
     * 取得表单里面所有的参数/值<br>
     * 多个值的默认以符号隔开保存
     *
     * @param request
     * @param notStart
     * @param separator
     * @return
     */
    public static Map<String, Object> getParam(HttpServletRequest request, String notStart,
                                               String separator) {
        Map<String, Object> map = new HashMap<>();
        Enumeration<String> paramNames = request.getParameterNames();
        while (paramNames.hasMoreElements()) {
            String paramName = paramNames.nextElement().toString();
            if (StringUtils.isBlank(notStart) || !paramName.startsWith(notStart)) {
                String[] paramValues = request.getParameterValues(paramName);
                String paramValue = StringUtils.join(separator, true, paramValues);
                map.put(paramName, paramValue);
            }
        }
        return map;
    }

    /**
     * 获取HTTP域名
     *
     * @param req
     * @return
     */
    public static String getHttpHost(HttpServletRequest req) {
        try {
            return new URL(req.getRequestURL().toString()).getHost();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取HTTP端口
     *
     * @param req
     * @return
     */
    public static int getHttpPort(HttpServletRequest req) {
        try {
            return new URL(req.getRequestURL().toString()).getPort();
        } catch (Exception e) {
            return 80;
        }
    }

    /**
     * 获得请求的绝对路径(不带参数)<br>
     * 如：http://riji.163.com/weblog/abc.do
     *
     * @param request
     * @return
     */
    public static String getUrl(HttpServletRequest request) {
        return request.getRequestURL().toString();
    }

    /**
     * 获得请求的相对路径(不带参数)<br>
     * 如：/weblog/abc.do
     *
     * @param request
     * @return
     */
    public static String getPath(HttpServletRequest request) {
        return request.getRequestURI();
    }

    /**
     * 获得请求的参数
     *
     * @param request
     * @return
     */
    public static String getQuery(HttpServletRequest request) {
        return request.getQueryString() != null ? request.getQueryString() : "";
    }

    /**
     * 获得页面来源（前一页面）
     *
     * @param request
     * @return
     */
    public static String getReferer(HttpServletRequest request) {
        return request.getHeader("Referer");
    }

    /**
     * 获取操作设备
     *
     * @param request
     * @return
     */
    public static String getUserAgent(HttpServletRequest request) {

        String userAgent = request.getHeader("user-agent").toLowerCase();
        if (StringUtils.isBlank(userAgent)) {
            userAgent = request.getHeader("User-Agent").toLowerCase();
        }

        String result = "";

        if (StringUtils.contains(userAgent, "mac")) {

            result = StringUtils.substringBetween(userAgent, "(", ";") + " ";
            int index = StringUtils.indexOf(userAgent, "version/");
            result += StringUtils.substring(userAgent, index, index + 10);

        } else if (StringUtils.contains(userAgent, "android")) {

            result = StringUtils.substringBetween(userAgent, ";", ";");

        } else {

            result = StringUtils.substringBetween(userAgent, "(", ")");

        }

        result += "  browser: ";
        if (userAgent.indexOf("msie 7") > 0) {
            result += "IE7";
        } else if (userAgent.indexOf("msie 8") > 0) {
            result += "IE8";
        } else if (userAgent.indexOf("msie 9") > 0) {
            result += "IE9";
        } else if (userAgent.indexOf("msie 10") > 0) {
            result += "IE10";
        } else if (userAgent.indexOf("msie") > 0) {
            result += "IE";
        } else if (userAgent.indexOf("opera") > 0) {
            result += "Opera";
        } else if (userAgent.indexOf("firefox") > 0) {
            result += "Firefox";
        } else if (userAgent.indexOf("gecko") > 0 && userAgent.indexOf("rv:11") > 0) {
            result += "IE11";
        } else if (userAgent.indexOf("edg") > 0) {
            result += "EDG";
        } else if (userAgent.indexOf("micromessenger") > 0) {
            result += "WeChat";
        } else if (userAgent.indexOf("chrome") > 0) {
            result += "Chrome";
        } else if (userAgent.indexOf("safari") > 0) {
            result += "Safari";
        }
        return result;
    }


    /**
     * 判断User-Agent 是不是来自于手机
     *
     * @return
     */
    public static boolean checkAgentIsMobile(HttpServletRequest request) {
        //定义移动端请求的所有可能类型
        final String[] agent = {"android", "iphone", "ipod", "ipad", "windows phone", "mqqbrowser"};

        String ua = request.getHeader("user-agent").toLowerCase();
        if (StringUtils.isBlank(ua)) {
            ua = request.getHeader("User-Agent").toLowerCase();
        }
        boolean flag = false;
        if (!ua.contains("windows nt") || (ua.contains("windows nt") && ua.contains("compatible; msie 9.0;"))) {
            // 排除 苹果桌面系统
            if (!ua.contains("windows nt") && !ua.contains("macintosh")) {
                for (String item : agent) {
                    if (ua.contains(item)) {
                        flag = true;
                        break;
                    }
                }
            }
        }
        return flag;
    }

}
